package com.zzyl.nursing.service.impl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.framework.web.service.TokenService;
import com.zzyl.nursing.dto.UserLoginRequestDto;
import com.zzyl.nursing.service.IWeChatService;
import com.zzyl.nursing.vo.LoginVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.FamilyMemberMapper;
import com.zzyl.nursing.domain.FamilyMember;
import com.zzyl.nursing.service.IFamilyMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

/**
 * 老人家属Service业务层处理
 *
 * @author Zhy
 * @date 2025-03-03
 */
@Service
@RequiredArgsConstructor
public class FamilyMemberServiceImpl extends ServiceImpl<FamilyMemberMapper, FamilyMember> implements IFamilyMemberService {

	private final FamilyMemberMapper familyMemberMapper;
	private final IWeChatService weChatService;
	private final TokenService tokenService;

	static List<String> DEFAULT_NICKNAME_PREFIX = ListUtil.of("生活更美好",
		"大桔大利",
		"日富一日",
		"好柿开花",
		"柿柿如意",
		"一椰暴富",
		"大柚所为",
		"杨梅吐气",
		"天生荔枝"
	);

	/**
	 * 查询老人家属
	 *
	 * @param id 老人家属主键
	 * @return 老人家属
	 */
	@Override
	public FamilyMember selectFamilyMemberById(Long id) {
		return familyMemberMapper.selectById(id);
	}

	/**
	 * 查询老人家属列表
	 *
	 * @param familyMember 老人家属
	 * @return 老人家属
	 */
	@Override
	public List<FamilyMember> selectFamilyMemberList(FamilyMember familyMember) {
		return familyMemberMapper.selectFamilyMemberList(familyMember);
	}

	/**
	 * 新增老人家属
	 *
	 * @param familyMember 老人家属
	 * @return 结果
	 */
	@Override
	public int insertFamilyMember(FamilyMember familyMember) {
		return familyMemberMapper.insert(familyMember);
	}

	/**
	 * 修改老人家属
	 *
	 * @param familyMember 老人家属
	 * @return 结果
	 */
	@Override
	public int updateFamilyMember(FamilyMember familyMember) {
		return familyMemberMapper.updateById(familyMember);
	}

	/**
	 * 批量删除老人家属
	 *
	 * @param ids 需要删除的老人家属主键
	 * @return 结果
	 */
	@Override
	public int deleteFamilyMemberByIds(Long[] ids) {
		return familyMemberMapper.deleteBatchIds(Arrays.asList(ids));
	}

	/**
	 * 删除老人家属信息
	 *
	 * @param id 老人家属主键
	 * @return 结果
	 */
	@Override
	public int deleteFamilyMemberById(Long id) {
		return familyMemberMapper.deleteById(id);
	}

	/**
	 * 小程序登录
	 *
	 * @return:
	 * @param:
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public LoginVo login(UserLoginRequestDto userLoginRequestDto) {
		// 1. 根据 opendId 查询用户信息
		String openId = weChatService.getOpenId(userLoginRequestDto.getCode());
		if (ObjUtil.isEmpty(openId)) {
			throw new BaseException("获取 openId 失败");
		}
		// 2. 获取用户信息
		FamilyMember member = this.lambdaQuery().eq(FamilyMember::getOpenId, openId).one();
		// 3. 如果为空，则创建用户
		if (ObjUtil.isNull(member)) {
			member = new FamilyMember();
			member.setOpenId(openId);
		}
		// 4. 获取手机号
		String phoneNumber = weChatService.getPhoneNumber(userLoginRequestDto.getPhoneCode());
		// 5. 新增或更新用户信息
		insertOrUpdate(member, phoneNumber);
		// 6. 生成 token
		Map<String, Object> claims = new HashMap<>();
		claims.put("id", member.getId());
		claims.put("nickName", member.getName());
		String token = tokenService.createToken(claims);
		// 7. 封装数据并返回
		LoginVo loginVo = new LoginVo();
		loginVo.setToken(token);
		loginVo.setNickName(member.getName());

		return loginVo;
	}

	/**
	 * 新增或更新用户信息
	 *
	 * @return:
	 * @param:
	 */
	private void insertOrUpdate(FamilyMember member, String phoneNumber) {
		// 更新手机号
		if (!StrUtil.equals(member.getPhone(), phoneNumber)) {
			member.setPhone(phoneNumber);
		}

		// 更新用户
		if (ObjUtil.isNotNull(member.getId())) {
			this.updateById(member);
			return;
		}

		// 新增用户
		String nickName = DEFAULT_NICKNAME_PREFIX.get((int) (Math.random() * DEFAULT_NICKNAME_PREFIX.size())) + StrUtil.sub(member.getPhone(),
			7,
			member.getPhone().length()
		);
		member.setName(nickName);
		this.save(member);
	}
}
